package com.example.mall.common.handler;

import com.example.mall.common.constants.BaseEnum;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author Mickey
 * @since 2021/10/26
 */
public class IntegerEnumTypeHandler<T extends Enum<?> & BaseEnum<?>> extends BaseTypeHandler<T> {

    private final Class<T> enumClazz;

    public IntegerEnumTypeHandler(Class<T> enumClazz) {
        this.enumClazz = enumClazz;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getCode());
    }

    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        int value = rs.getInt(columnName);
        return rs.wasNull() ? null : fromValue(value);
    }

    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        int value = rs.getInt(columnIndex);
        return rs.wasNull() ? null : fromValue(value);
    }

    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        final int value = cs.getInt(columnIndex);
        return cs.wasNull() ? null : fromValue(value);
    }

    private T fromValue(int value) {
        for (T e : this.enumClazz.getEnumConstants()) {
            if (e.getCode() == value) {
                return e;
            }
        }
        throw new IllegalArgumentException("illegal value  " + value + " for enum " + this.enumClazz.getName());
    }
}
